//
//  XFYMotionView.m
//  SDKSample
//
//  Created by 小肥羊 on 15/12/15.
//  Copyright © 2015年 Zhu‘s Game House. All rights reserved.
//

#import "XFYMotionView.h"
#import <CoreMotion/CoreMotion.h>

static const CGFloat XFYMotionViewRotationMinimumTreshold = 0.1f;       /**< 敏感度 */
static const CGFloat XFYMotionGyroUpdateInterval = 1 / 100;             /**< 更新间隔 */
static const CGFloat XFYMotionViewRotationFactor = 0.2f;                /**< 移动速度 */

@interface XFYMotionView ()

@property (nonatomic, assign) CGRect viewFrame;

@property (nonatomic, strong) CMMotionManager *motionManager;
@property (nonatomic, strong) UIScrollView *scrollView;
@property (nonatomic, strong) UIImageView *imageView;

@property (nonatomic, assign) CGFloat motionRate;
@property (nonatomic, assign) NSInteger minimumOffset;
@property (nonatomic, assign) NSInteger maximumOffset;

@end

@implementation XFYMotionView
#pragma mark - 初始化
- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        self.viewFrame = frame;
        [self initValue];
    }
    return self;
}

- (void)initValue
{
    self.motionManager = [[CMMotionManager alloc] init];
    self.motionManager.gyroUpdateInterval = XFYMotionGyroUpdateInterval;
    
    self.scrollView = [[UIScrollView alloc] initWithFrame:(CGRect){CGPointZero,self.viewFrame.size}];
    [self.scrollView setBounces:NO];
    [self.scrollView setContentSize:CGSizeZero];
    [self addSubview:self.scrollView];
    
    self.imageView = [[UIImageView alloc] init];
    [self.scrollView addSubview:self.imageView];
    
    self.minimumOffset = 0;
    self.motionEnabled = YES;
}

#pragma mark - Set属性
- (void)setImage:(UIImage *)image
{
    _image = image;
    [self.imageView setImage:_image];
    
    if (_image.size.height/_image.size.width < self.viewFrame.size.height/self.viewFrame.size.width) {
        CGFloat width = self.viewFrame.size.height / _image.size.height * _image.size.width;
        [self.imageView setFrame:CGRectMake(0, 0, width, self.viewFrame.size.height)];
        self.scrollView.contentSize = self.imageView.bounds.size;
        self.scrollView.contentOffset = CGPointMake((self.scrollView.contentSize.width - self.scrollView.frame.size.width) / 2, 0);
        self.motionRate = _image.size.width / self.viewFrame.size.width * XFYMotionViewRotationFactor;
        self.maximumOffset = self.scrollView.contentSize.width - self.scrollView.frame.size.width;
    } else {
        CGFloat height = self.viewFrame.size.width / _image.size.width * _image.size.height;
        [self.imageView setFrame:CGRectMake(0, 0, self.viewFrame.size.width, height)];
        self.scrollView.contentSize = self.imageView.bounds.size;
        self.scrollView.contentOffset = CGPointMake(0, (self.scrollView.contentSize.height - self.scrollView.frame.size.height) / 2);
        self.motionRate = _image.size.height / self.viewFrame.size.height * XFYMotionViewRotationFactor;
        self.maximumOffset = self.scrollView.contentSize.height - self.scrollView.frame.size.height;
    }
}
- (void)setMotionEnabled:(BOOL)motionEnabled
{
    _motionEnabled = motionEnabled;
    if (_motionEnabled) {
        [self startMonitoring];
    } else {
        [self stopMonitoring];
    }
}

#pragma mark - Core Motion
- (void)startMonitoring
{
    if (![self.motionManager isGyroActive] && [self.motionManager isGyroAvailable]) {
        [self.motionManager startGyroUpdatesToQueue:[NSOperationQueue currentQueue]
                                    withHandler:^(CMGyroData *gyroData, NSError *error) {
                                        if (self.image.size.height/self.image.size.width < self.viewFrame.size.height/self.viewFrame.size.width) {
                                            CGFloat rotationRate = gyroData.rotationRate.y;
                                            if (fabs(rotationRate) >= XFYMotionViewRotationMinimumTreshold) {
                                                CGFloat offsetX = self.scrollView.contentOffset.x - rotationRate * self.motionRate;
                                                if (offsetX > self.maximumOffset) {
                                                    offsetX = self.maximumOffset;
                                                } else if (offsetX < self.minimumOffset) {
                                                    offsetX = self.minimumOffset;
                                                }
                                                [UIView animateWithDuration:0.3f
                                                                      delay:0.0f
                                                                    options:UIViewAnimationOptionBeginFromCurrentState | UIViewAnimationOptionAllowUserInteraction | UIViewAnimationOptionCurveEaseOut
                                                                 animations:^{
                                                                     [self.scrollView setContentOffset:CGPointMake(offsetX, 0) animated:NO];
                                                                 }
                                                                 completion:nil];
                                            }
                                        } else {
                                            CGFloat rotationRate = gyroData.rotationRate.x;
                                            if (fabs(rotationRate) >= XFYMotionViewRotationMinimumTreshold) {
                                                CGFloat offsetY = self.scrollView.contentOffset.y - rotationRate * self.motionRate;
                                                if (offsetY > self.maximumOffset) {
                                                    offsetY = self.maximumOffset;
                                                } else if (offsetY < self.minimumOffset) {
                                                    offsetY = self.minimumOffset;
                                                }
                                                [UIView animateWithDuration:0.3f
                                                                      delay:0.0f
                                                                    options:UIViewAnimationOptionBeginFromCurrentState | UIViewAnimationOptionAllowUserInteraction | UIViewAnimationOptionCurveEaseOut
                                                                 animations:^{
                                                                     [self.scrollView setContentOffset:CGPointMake(0, offsetY) animated:NO];
                                                                 }
                                                                 completion:nil];
                                            }
                                        }
                                    }];
    } else {
        NSLog(@"There is not available gyro.");
    }
}

- (void)stopMonitoring
{
    [self.motionManager stopGyroUpdates];
}


/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
    // Drawing code
}
*/

@end
